#include "bsp_i2c.h"


#if I2C_ENABLE

#define I2CUseSoftDelay 0 //1：使用软件延时;  0：使用硬件延时


#if I2CUseSoftDelay == 1

	#define DelayConst     0x01    //可以用示波器测量
	#define StopDelayConst 0x4fff  //I2C总线停止时，延时时间可加长，可实际更改测试一下
  

	static void I2cSoftDelay(unsigned long cnt) //I2C延时(非标准延时,请根据MCU速度 调节大小)
	{
		while(cnt--);
	}
  
	#define 	I2c_Delay(n)  		I2cSoftDelay(n)
	#define   	I2c_StopDelay()  	I2cSoftDelay(StopDelayConst)


#else
	
	#define 	DelayConst     		3   //可以用示波器测量
	#define 	StopDelayConst 		3  //
	#define 	I2c_Delay(n)   		SysTick_DelayUs(n) //精确延时
	#define   	I2c_StopDelay()  	SysTick_DelayMs(StopDelayConst) //精确延时

	
#endif
	
	

void I2cGpioInit(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	
    I2C_SCL_APBxClock_FUN(I2C_SCL_APBxClock_CLK, ENABLE);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStruct.GPIO_Pin  = I2C_SCL_GPIO_PIN ;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(I2C_SCL_GPIO_PORT, &GPIO_InitStruct);
	
	I2C_SDA_APBxClock_FUN(I2C_SDA_APBxClock_CLK, ENABLE);
	GPIO_InitStruct.GPIO_Pin  = I2C_SDA_GPIO_PIN ;
	GPIO_Init(I2C_SDA_GPIO_PORT, &GPIO_InitStruct);
	
	I2C_SCL_LOW ;
	I2C_SDA_LOW ;
	
}

   
void I2cStart(void)
{
	I2C_SCL_HIGH; //SCL 高
	I2c_Delay(DelayConst);
	
	I2C_SDA_HIGH;  //SDA 高->低
	I2c_Delay(DelayConst);
	
	I2C_SDA_LOW ;
	I2c_Delay(DelayConst);
	
	I2C_SCL_LOW ;//SCL低，为了钳住I2C总线，准备发送或接收数据
	I2c_Delay(DelayConst);
	
}
void I2cStop(void)
{
	I2C_SDA_LOW ;//SDA 低->高
	I2c_Delay(DelayConst);
	
	I2C_SCL_HIGH; //SCL 高
	I2c_Delay(DelayConst);
	
	I2C_SDA_HIGH;  
	I2c_StopDelay();
	
}
void I2cAck(void)
{
	I2C_SCL_LOW ;//SCL低, 准备数据
	I2c_Delay(DelayConst);
	
	I2C_SDA_LOW ;//SDA 低
	I2c_Delay(DelayConst);
	
	I2C_SCL_HIGH; //SCL 高
	I2c_Delay(DelayConst);
	
	I2C_SCL_LOW; //SCL 低
	I2c_Delay(DelayConst);
	
	I2C_SDA_HIGH;//数据总线空闲
	
	
}
void I2cNoAck(void)
{
	I2C_SCL_LOW ;//SCL低, 准备数据
	I2c_Delay(DelayConst);
	
	I2C_SDA_HIGH ;//SDA 高，非应答是将SDA置高实现
	I2c_Delay(DelayConst);
	
	I2C_SCL_HIGH; //SCL 高
	I2c_Delay(DelayConst);
	
	I2C_SCL_LOW; //SCL 低
	I2c_Delay(DelayConst);
	
	I2C_SDA_HIGH;//数据总线空闲
}
unsigned char I2cReadAck(void)
{
	unsigned char ack;
	
	I2C_SCL_LOW; //SCL 低
	I2c_Delay(DelayConst);
	
	I2C_SDA_HIGH ;//释放SDA
	I2c_Delay(DelayConst);
	
	I2C_SCL_HIGH; //SCL 高，置高，读数据
	I2c_Delay(DelayConst);
	
	if(I2C_SDA_READ)
		ack = I2C_NOACK;//非应答
	else
		ack =I2C_ACK;//应答
	
	I2C_SCL_LOW; //SCL 低
	I2c_Delay(DelayConst);
	
	return ack;
	
	
}
void I2cWriteByte(unsigned char ByteData)
{
	unsigned char cnt ;
	
	for(cnt=0; cnt<8;cnt++)
	{
			I2C_SCL_LOW; //SCL 低(SCL为低电平时允许SDA变化)
	    I2c_Delay(DelayConst);
		
		  if(ByteData & 0x80)
			  I2C_SDA_HIGH ;
			else 
				I2C_SDA_LOW ;
			
			I2c_Delay(DelayConst);
			
		  I2C_SCL_HIGH; //SCL 高 ，送数据
	    I2c_Delay(DelayConst);
			
			ByteData <<= 1;
		
	}
}

void I2cReadByte(unsigned char *ByteData)
{
	unsigned char cnt;
	
	I2C_SCL_LOW; //SCL 低(SCL为低电平时允许SDA变化)
	I2c_Delay(DelayConst);
	
	I2C_SDA_HIGH ;//释放SDA
	I2c_Delay(DelayConst);//测试是否需要延时
	
	for(cnt=0;cnt<8;cnt++)
	{
		I2C_SCL_HIGH; //SCL高，准备读数据
	  I2c_Delay(DelayConst);
		
		*ByteData <<=1;
		
		if(I2C_SDA_READ)
			*ByteData |=0x1;
		
		
    I2C_SCL_LOW; //SCL 低(SCL为低电平时允许SDA变化)
	  I2c_Delay(DelayConst);	
			
	}
}

#endif











